package com.shiku.im.user.dao.impl;


import com.alibaba.fastjson.JSONObject;
import com.shiku.im.comm.utils.StringUtil;
import com.shiku.im.repository.MongoRepository;
import com.shiku.im.user.dao.UserChanceSettingsService;
import com.shiku.im.user.entity.UserChanceSettings;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Repository
public class UserChanceSettingsServiceImpl extends MongoRepository<UserChanceSettings, Integer> implements UserChanceSettingsService {

    @Override
    public Class<UserChanceSettings> getEntityClass() {
        return UserChanceSettings.class;
    }

    @Override
    public UserChanceSettings getSettingsByUserId(int userId) {
        UserChanceSettings settings = findOne("_id", userId);
        if(settings == null){
            settings = new UserChanceSettings();
        }
        UserChanceSettings defaultSettings = getDefaultSettings();
        if(StringUtil.isEmpty(settings.getSettings())){
            settings.setSettings(defaultSettings.getSettings());
        }
        if(StringUtil.isEmpty(settings.getBigSettings())){
            settings.setBigSettings(defaultSettings.getBigSettings());
        }
        if(settings.getBigStart() == null){
            settings.setBigStart(defaultSettings.getBigStart());
        }
        return settings;
    }

    @Override
    public UserChanceSettings getDefaultSettings() {
        UserChanceSettings settings = findOne("_id", 1000);
        if(settings == null){
            settings = new UserChanceSettings();
            String initData = "{\"10-10\":1.083E-5,\"10-5\":0.02167183,\"10-4\":0.05417957,\"10-3\":0.12383901,\"10-2\":0.26315789,\"10-1\":0.52631579,\"5-1\":0.35714286,\"5-2\":0.10989011,\"6-1\":0.4,\"5-3\":0.02747253,\"6-2\":0.14285714,\"7-1\":0.4375,\"5-4\":0.004995,\"6-3\":0.04395604,\"7-2\":0.175,\"8-1\":0.47058824,\"10-9\":1.0825E-4,\"5-5\":4.995E-4,\"6-4\":0.01098901,\"7-3\":0.0625,\"8-2\":0.20588235,\"9-1\":0.5,\"10-8\":5.9538E-4,\"6-5\":0.001998,\"7-4\":0.01923077,\"8-3\":0.08235294,\"9-2\":0.23529412,\"10-7\":0.00238152,\"6-6\":1.998E-4,\"7-5\":0.00480769,\"8-4\":0.02941176,\"9-3\":0.10294118,\"10-6\":0.00773994,\"7-6\":8.7413E-4,\"8-5\":0.00904977,\"9-4\":0.04117647,\"7-7\":8.741E-5,\"8-6\":0.00226244,\"9-5\":0.01470588,\"8-7\":4.1135E-4,\"9-6\":0.00452489,\"8-8\":4.114E-5,\"9-7\":0.00113122,\"9-8\":2.0568E-4,\"9-9\":2.057E-5}";
            settings.setSettings(initData);
            settings.setBigSettings(initData);
            settings.setBigStart(100f);
            save(settings);
        }
        return settings;
    }

    @Override
    public void addOrUpdateSettings(int userId, String str, Float bigStart, String bigStr) {
        UserChanceSettings settings = findOne("_id", userId);
        if(settings == null){
            settings = new UserChanceSettings();
            settings.setUserId(userId);
        }
        if(!StringUtil.isEmpty(str)){
            settings.setSettings(str);
        }
        if(bigStart != null){
            settings.setBigStart(bigStart);
        }
        if(!StringUtil.isEmpty(bigStr)){
            settings.setBigSettings(bigStr);
        }
        save(settings);
    }

    @Override
    public void addOrUpdateSettingsToAll(String str, Float bigStart, String bigStr) {
        Update update = createUpdate();
        if(!StringUtil.isEmpty(str)){
            update.set("settings", str);
        }
        if(bigStart != null){
            update.set("bigStart", bigStart);
        }
        if(!StringUtil.isEmpty(bigStr)){
            update.set("bigSettings", bigStr);
        }
        update(new Query(Criteria.where("_id").ne(1000)), update);
    }

    @Override
    public UserChanceSettings init(int userId) {
        UserChanceSettings settings = new UserChanceSettings();
        settings.setUserId(userId);
        JSONObject jsonObject = new JSONObject();
        for (int i = 5; i < 11; i++) {
            for (int j = 0; j < i; j++) {
                jsonObject.put(i + "-" + (j + 1), getReallyProbability(i, j + 1));
            }
        }
        settings.setSettings(jsonObject.toJSONString());
        save(settings);
        return settings;
    }

    private double getReallyProbability(int packetCount, int bombCount) {
        BigInteger n = new BigInteger(String.valueOf(packetCount));
        BigInteger l = new BigInteger(String.valueOf(bombCount));
        BigInteger nine = new BigInteger("9");

        double v = factorial(n).multiply(factorial(n.add(nine).subtract(l))).doubleValue() / (factorial(n.add(nine)).multiply(factorial(n.subtract(l)))).doubleValue();
        BigDecimal bigDecimal = new BigDecimal(v);
        BigDecimal result = bigDecimal.setScale(8, BigDecimal.ROUND_HALF_UP);
        return result.doubleValue();
    }

    private BigInteger factorial(BigInteger number) {
        BigInteger one = new BigInteger("1");
        if (number.compareTo(one) < 1)
            return one;
        else
            return number.multiply(factorial(number.subtract(one)));
    }

    private int[] getNums(String title) {
        StringBuilder builder = new StringBuilder("[");
        String pattern = "[^0-9]";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(title);
        while (m.find()) {
            String s = m.group();
            if (s.equals("\\")) {
                s = "\\\\";
            }
            builder.append(s);
        }
        builder.append("]");
        if (!builder.toString().equals("[]")) {
            String[] haveMoney = title.split(builder.toString());
            if (haveMoney.length == 2) {
                title = haveMoney[1];
            }
        }

        int[] nums;
        if (title.equals("财源滚滚，心想事成") || title.equals("恭喜发财,万事如意")) {
            nums = new int[1];
            nums[0] = 1;
        } else {
            try {
                nums = new int[title.length()];
                String[] split = title.split("");
                for (int i = 0; i < split.length; i++) {
                    String s = split[i];
                    nums[i] = Integer.parseInt(s);
                }
            } catch (NumberFormatException e) {
//                nums = getHaveMoneyNums(title);
//                if (title== null) {
//                    return null;
//                }
                return null;
            }
        }
        //去重
        HashSet<Integer> list = new HashSet<>();
        for (int num : nums) {
            list.add(num);
        }
        int[] newNums = new int[list.size()];
        int i = 0;
        for (Integer integer : list) {
            newNums[i] = integer;
            i++;
        }
        return newNums;
    }

}
